Thread: [GCC] Compiling for a generic x86 architecture

  1. #1
    Registered User
    Join Date
    May 2010
    Posts
    13

    [GCC] Compiling for a generic x86 architecture

    Hi,
    I wrote a simple hello world program,
    when I try to compile it on Linux with the following option, I have no problem:

    gcc hello.c -mtune=generic


    While on Windows (MinGW) I get this error:

    hello.c:1 error: bad value (generic) for -mtune = switch

    Why?

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Question: why do you want to use this option?
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    13
    Quote Originally Posted by MK27 View Post
    Question: why do you want to use this option?
    I need to compile hello.c for a generic x86 CPU...
    am I dooing wrong?

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    I know next to nothing about this kind of thing, if you mean you are "cross compiling" -- that is, compiling for an architecture other than the one you are compiling on.

    If you just want to compile and run the program on the computer you are currently using, you don't need to use this switch.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    May 2010
    Posts
    13
    The problem is that I don't need an executable optimized for my machine but a generic executable for the most common processors. And on linux it works fine...

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by mario++ View Post
    The problem is that I don't need an executable optimized for my machine but a generic executable for the most common processors. And on linux it works fine...
    So you are not already using x86 machine? Again, I don't know much about this, but if you do not use -mtune, then code compiled on an x86 will run fine on all other x86 (AMD, intel) systems. In other words, not using it does not mean it "defaults" to -mtune=native, it simply means none of the potential mtune optimizations will be used. Which for something like "hello world", those optimizations will be totally irrelevant.

    Anyway, probably the gcc versions are different. You can get the version w/ "gcc -v". Probably MinGW does not have all the features of the gcc you are using on linux.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    Registered User
    Join Date
    May 2010
    Posts
    13
    Quote Originally Posted by MK27 View Post
    Anyway, probably the gcc versions are different. You can get the version w/ "gcc -v". Probably MinGW does not have all the features of the gcc you are using on linux.
    Thanks, I lerned that MinGW GCC 3.4.5 does not support -mtune=generic option

    Quote Originally Posted by MK27 View Post
    In other words, not using it does not mean it "defaults" to -mtune=native
    What does -mtune=generic mean on Linux? Do it mean -mtune=i386?

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by mario++ View Post
    What does -mtune=generic mean on Linux? Do it mean -mtune=i386?
    Like I said, I've never used this option, and I think you have been distracted by it and believe it possess some significance it does not have (no big deal). I believe the purpose of mtune would mostly be for "cross compiling", where you are compiling an executable that will not run on the machine it is compiled on, but instead, a completely different piece of hardware, or to optimize for a particular machine including the one you are compiling on. But this is not necessary for hello world.

    You would only want to think about this if you are aware of some feature of your processor that you are trying to exploit. If this feature is specific to a particular processor, then the compiler will not use it unless:

    1) it knows about it, ie, the compiler has been designed with such potential.
    2) you instruct the compiler to use those processor specific features with a switch such as this one.

    By "feature" I mean specific asm (assembly) level commands (don't ask me for any, I dunno assembly!) If you are familiar with these things, -mtune may be interesting to you. If not, don't worry about it.

    The "generic" option is described this way:
    Quote Originally Posted by man gcc
    generic
    Produce code optimized for the most common IA32/AMD64/EM64T
    processors. If you know the CPU on which your code will run,
    then you should use the corresponding -mtune option instead of
    -mtune=generic. But, if you do not know exactly what CPU users
    of your application will have, then you should use this option.

    As new processors are deployed in the marketplace, the behavior
    of this option will change. Therefore, if you upgrade to a
    newer version of GCC, the code generated option will change to
    reflect the processors that were most common when that version
    of GCC was released.
    What I take from this is: there are some new features that are common to many or most newer x86 processors that are still not part of the basic x86 set of (asm) instructions. So "generic" will exploit those. However, that means there will still be some x86's that don't use these features that your code will now not work on!

    If your goal is to compile an executable that will run on all x86 processors then don't use -mtune! This is not used to select the processor! You don't have to do that!
    Last edited by MK27; 06-04-2010 at 12:01 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    MinGW(and all other cross compilers) has serious bugs(understandably, Windows is a whole different world than that that gcc and ld were made to run in). For example, MinGW - OSDev Wiki.

    Just use -m32 with gcc and link as the desired format.

    I suspect that's more your problem that x86 incompatibility. It's not that the code isn't x86 compatible, it's that it's the wrong executable format. Windows primarily uses PE and Linux uses a.out and ELF(but can load PEs with Wine).

  10. #10
    Registered User jephthah's Avatar
    Join Date
    May 2010
    Location
    seattle
    Posts
    49
    Quote Originally Posted by User Name: View Post
    MinGW(and all other cross compilers) has serious bugs
    hyperbole much?

    every compiler has bugs. MinGW is entirely suitable for 99.99% of the needs of any C programmer on these boards. The dude obviously isnt building a real-time operating system


    .
    Last edited by jephthah; 06-04-2010 at 10:53 PM.

  11. #11
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    1. (GCC 2.95) ld -r -d ... doesn't get rid of all the common variables.
    2. (GCC 2.95) BSS size is stored in the wrong location of the section header, so MinGW does not correctly interoperate with NASM.
    3. ld -Ttext=NNN ... doesn't put the .text section at the correct address unless you also use the --image-base=0 option.
    4. Linker claims to support ELF, but says "PE operations on non PE file" if you try to use ELF.
    Yeah, section headers, .text section alignment, and ELF are all useless right(assuming the wiki I referenced is right that these problems exist)? #1 means you can't even link two object files into one w/o a (albeit simple) linker script.

    Pass "hello.c -Wl,--oformat,pei-i386"(change i386 to x86-64 if your Windows is 64 bit)
    This will have ld link you file as a PE, usable by Windows.

    The command "objdump -i" will list all format's that can be compiled/linked by the software on your system.

  12. #12
    Registered User
    Join Date
    May 2010
    Posts
    13
    Quote Originally Posted by User Name: View Post
    Just use -m32 with gcc and link as the desired format.
    As I found in manual for -m32:
    "The 32-bit environment sets int, long and pointer to 32 bits and generates code that runs on any i386 system."

    What do "generates code that runs on any i386 system." mean? Perhaps does -m32 do something like a -mtune=generic option? Or does it only set long and pointer to 32 bits?

  13. #13
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    "-m32" tells gcc to produce code for 32 bit protected/compatibility mode. That has to do with the type of assembly it produces. Calling conventions are also different in 64 bit mode(the successor to 32 bit). And, like you mentioned, variable sizes are different in different modes.

    "-mtune=*", from what I can tell, just narrows what processors gcc will optimize for(kinda like , with generic as you're using, gcc will avoid any SSE* or other instruction sets that were introduced after the 80386. Put simply, it's worthless, don't use it, unless you really know why you're using it.

    Telling ld to link it as a pei-i386 will imply you want i386 code. And you would get errors if something was wrong that would cause the code not to be for the i386.

    You're not going to get the same build to run on Linux and Windows. It's a problem of executable formats, the info in executables that describes to the OS how to load the executable into memory is OS specific, what's perfectly clear to NT will make no sense to Linux.

    What Windows are you testing on, is it x86 or x64? And what Linux(i386 or x86-64)? I'll give you the exact command line to build with, but I have to know what mode those OSes are running in.

  14. #14
    Registered User
    Join Date
    May 2010
    Posts
    13
    Quote Originally Posted by User Name: View Post
    "-m32" tells gcc to produce code for 32 bit protected/compatibility mode. That has to do with the type of assembly it produces. Calling conventions are also different in 64 bit mode(the successor to 32 bit). And, like you mentioned, variable sizes are different in different modes.

    "-mtune=*", from what I can tell, just narrows what processors gcc will optimize for(kinda like , with generic as you're using, gcc will avoid any SSE* or other instruction sets that were introduced after the 80386. Put simply, it's worthless, don't use it, unless you really know why you're using it.

    Telling ld to link it as a pei-i386 will imply you want i386 code. And you would get errors if something was wrong that would cause the code not to be for the i386.

    You're not going to get the same build to run on Linux and Windows. It's a problem of executable formats, the info in executables that describes to the OS how to load the executable into memory is OS specific, what's perfectly clear to NT will make no sense to Linux.

    What Windows are you testing on, is it x86 or x64? And what Linux(i386 or x86-64)? I'll give you the exact command line to build with, but I have to know what mode those OSes are running in.
    My Windows 7 runs in x86 mode (CPU: Athlon 64), and Debian i386 (CPU AMD Athlon XP).

    As I said, my intention is to produce a code (two executables, one for Windows OS and the other for Linux) that will work best way on most of the end-users computers.
    Last edited by mario++; 06-05-2010 at 06:47 AM.

  15. #15
    Password:
    Join Date
    Dec 2009
    Location
    NC
    Posts
    587
    Use "-m32 -Wl,--oformat,pei-i386" for 32 bit Windows
    Use "-m64 -Wl,--oformat,pei-x86-64" for 64 bit Windows
    Use "-m32 -Wl,--oformat,elf32-i386" for 32 bit Linux
    Use "-m64 -Wl,--oformat,elf64-x86-64" for 64 bit Linux

    That should work, if it doesn't, post the error you get.

    I should note: the "-Wl" option affects gcc operation in no way. It just tells gcc to pass the following args as arguments to ld.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. Resource ICONs
    By gbaker in forum Windows Programming
    Replies: 4
    Last Post: 12-15-2003, 07:18 AM